#!/usr/bin/python
# -*- coding: utf-8 -*-

# gmailatom 0.0.1
#
# HOW TO USE:
# 1) Create an instance of 'GmailAtom' class. The two arguments
#    its constructor take are the username (including '@gmail.com')
#    and the password.
# 2) To retrieve the account status call 'refreshInfo()'.
# 3) To get the unread messages count call 'getUnreadMsgCount()'.
#    You MUST call 'refreshInfo()' at least one time before using
#    this method or it will return zero.
# 4) To get specific information about an unread email you must
#    call the corresponding getter method passing to it the number
#    of the message. The number zero represents the newest one.
#    You MUST call 'refreshInfo()' at least one time before using any
#    getter method or they will return an empty string.
#    The getter methods are:
#	getMsgTitle(index)
#	getMsgSummary(index)
#	getMsgAuthorName(index)
#	getMsgAuthorEmail(index)
#
# by Juan Grande
# juan.grande@gmail.com

from xml.sax.handler import ContentHandler
from xml import sax
import urllib2

# Auxiliar structure
class Mail:
	title=""
	summary=""
	author_name=""
	author_addr=""

# Sax XML Handler
class MailHandler(ContentHandler):
	
	# Tags
	TAG_FEED = "feed"
	TAG_FULLCOUNT = "fullcount"
	TAG_ENTRY = "entry"
	TAG_TITLE = "title"
	TAG_SUMMARY = "summary"
	TAG_AUTHOR = "author"
	TAG_NAME = "name"
	TAG_EMAIL = "email"
	
	# Path the information
	PATH_FULLCOUNT = [ TAG_FEED, TAG_FULLCOUNT ]
	PATH_TITLE = [ TAG_FEED, TAG_ENTRY, TAG_TITLE ]
	PATH_SUMMARY = [ TAG_FEED, TAG_ENTRY, TAG_SUMMARY ]
	PATH_AUTHOR_NAME = [ TAG_FEED, TAG_ENTRY, TAG_AUTHOR, TAG_NAME ]
	PATH_AUTHOR_EMAIL = [ TAG_FEED, TAG_ENTRY, TAG_AUTHOR, TAG_EMAIL ]

	def __init__(self):
		self.startDocument()

	def startDocument(self):
		self.entries=list()
		self.actual=list()
		self.mail_count="0"

	def startElement( self, name, attrs):
		# update actual path
		self.actual.append(name)

		# add a new email to the list
		if name=="entry":
			m = Mail()
			self.entries.append(m)

	def endElement( self, name):
		# update actual path
		self.actual.pop()

	def characters( self, content):
		# New messages count
		if (self.actual==self.PATH_FULLCOUNT):
			self.mail_count = self.mail_count+content

		# Message title
		if (self.actual==self.PATH_TITLE):
			temp_mail=self.entries.pop()
			temp_mail.title=temp_mail.title+content
			self.entries.append(temp_mail)

		# Message summary
		if (self.actual==self.PATH_SUMMARY):
			temp_mail=self.entries.pop()
			temp_mail.summary=temp_mail.summary+content
			self.entries.append(temp_mail)

		# Message author name
		if (self.actual==self.PATH_AUTHOR_NAME):
			temp_mail=self.entries.pop()
			temp_mail.author_name=temp_mail.author_name+content
			self.entries.append(temp_mail)

		# Message author email
		if (self.actual==self.PATH_AUTHOR_EMAIL):
			temp_mail=self.entries.pop()
			temp_mail.author_addr=temp_mail.author_addr+content
			self.entries.append(temp_mail)

	def getUnreadMsgCount(self):
		return int(self.mail_count)

# The mail class
class GmailAtom:

	realm = "New mail feed"
	host = "https://mail.google.com"
	url = host + "/mail/feed/atom"

	def __init__(self, user, pswd):
		self.m = MailHandler()
		# initialize authorization handler
		auth_handler = urllib2.HTTPBasicAuthHandler()
		auth_handler.add_password( self.realm, self.host, user, pswd)
		opener = urllib2.build_opener(auth_handler)
		urllib2.install_opener(opener)

	def sendRequest(self):
		return urllib2.urlopen(self.url)

	def refreshInfo(self):
		# get the page and parse it
		p = sax.parseString( self.sendRequest().read(), self.m)

	def getUnreadMsgCount(self):
		return self.m.getUnreadMsgCount()

	def getMsgTitle(self, index):
		return self.m.entries[index].title

	def getMsgSummary(self, index):
		return self.m.entries[index].summary

	def getMsgAuthorName(self, index):
		return self.m.entries[index].author_name

	def getMsgAuthorEmail(self, index):
		return self.m.entries[index].author_email

def announce(title, author, summary):
    import os
    import sys
    if sys.platform == 'darwin':
        # MAC OS X - Use growlnotify
        if os.path.exists('/usr/local/bin/growlnotify'):
            from subprocess import call
            call(['/usr/local/bin/growlnotify',
                '-m',author+': '+title,'-a','Mail.app'])
    elif sys.platform == 'linux2':
        # Linux - Use notify-send
        if os.path.exists('/usr/bin/notify-send'):
            from subprocess import call
            os.environ['DISPLAY']=':0'
            call(['/usr/bin/dbus-launch',
                '/usr/bin/notify-send',
                '-t', '5000',
                author+': '+title,
                summary])
            
def get_creds():
    import re
    import os
    pattern = re.compile('"([^"]*)"')
    
    home_dir = os.environ['HOME']
    muttrc = open(home_dir + '/.muttrc','r')
    for line in muttrc:
        if line.find('imap_pass') > 0: 
            password = pattern.findall(line)[0]
        if line.find('imap_user') > 0: 
            username = pattern.findall(line)[0]

    return [username, password]

def main():
    [uname, passwd] = get_creds()
    gmail = GmailAtom(uname, passwd)
    gmail.refreshInfo()
    unread_num = gmail.getUnreadMsgCount()
    if(unread_num > 0):
        title = gmail.getMsgTitle(0)
        author = gmail.getMsgAuthorName(0)
        summary = gmail.getMsgSummary(0)

    if unread_num > 1: 
        title = title + '  ['+str(unread_num-1)+' more]'

    if(unread_num > 0):
        announce(title, author, summary)

if __name__ == '__main__':
    main()
